<?php
/**
 * 第三方授权处理
 */
namespace app\index\controller;

use app\common\controller\Homebase;

class Oauth extends Homebase
{
    public function initialize()
    {
        parent::initialize();
    }

    public function logoutAuth()
    {
        set_login_cookie();
        $back_url = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '/';
        header('location: ' . $back_url);
    }

    // 第三方登录 - 授权页面
    public function loginAuth()
    {
        $toProvider = input('param.redirectToProvider', '', config('tst_filter'));
        $back_url   = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '';

        $this->_checkProvider($toProvider);
        $this->_authAndAccessToken($toProvider, '', $back_url);
    }

    // 第三方登录 - 确认授权后回调地址处理
    public function authProviderCallback()
    {
        $provider = input('param.provider', '', config('tst_filter'));
        $code     = input('param.code', '', config('tst_filter'));
        $state    = input('param.state', '', config('tst_filter'));
        $back_url = '';
        if (!empty($state)) {
            $state    = str_replace(' ', '+', $state);
            $back_url = \util\Mcrypt::authcode($state, 'DECODE');
        }
        $this->_checkProvider($provider);
        if (empty($code)) {
            $this->error('缺少授权code值');
        }
        
        $this->_authAndAccessToken($provider, $code, $back_url);
    }

    /**
     * 第三方登录 - 验证平台参数
     * @param  string $provider 平台参数值
     * @return mixed
     */
    private function _checkProvider($provider = '')
    {
        $provider_arr = ['weibo', 'qq'];
        if (!in_array($provider, $provider_arr)) {
            $this->error('授权登录平台标识错误');
        }
    }

    /**
     * 第三方登录 - 授权和获取access_token
     * @param  string $provider 平台参数值
     * @param  string $code     获取token的code值，第三方平台返回
     * @param  string $back_url 登录整个后的跳转URL地址
     * @return mixed
     */
    private function _authAndAccessToken($provider = '', $code = '', $back_url = '')
    {
        $http         = is_ssl() ? 'https://' : 'http://';
        $domain       = $_SERVER['HTTP_HOST'];
        $redirect_uri = $http . $domain . '/login/authCallback/' . $provider;
        $back_url     = !empty($back_url) ? $back_url : $http . $domain;

        $oauthProvider = '';
        switch ($provider) {
            case 'weibo':
                $oauthProvider = new \oauth\weibo();
                break;
            case 'qq':
                $oauthProvider = new \oauth\qq();
                break;
        }

        if (empty($code)) {
            $state = \util\Mcrypt::authcode($back_url);
            $oauthProvider->authorize($redirect_uri, $state);
            return false;
        }

        // 获取access_token值
        $result = $oauthProvider->getAccessToken($redirect_uri, $code);
        if (empty($result) || (!empty($result) && empty($result['res_json']))) {
            $this->error('未获取到授权信息，请重新授权登录');
        }
        $log_dir = 'oauth/' . $provider;
        $log_str = '___' . $provider . '___ date: ' . date('Y-m-d H:i:s') . 'AccessToken: ' . $result['res_json'];
        printLog($log_str, $log_dir);
        $token_info = json_decode($result['res_json'], true);
        if (!empty($token_info['error_code'])) {
            $this->error('授权登录错误，错误码：' . $token_info['error_code'] . '；Error：' . $token_info['error']);
        }
        // 保存token信息
        $token_model = new \app\common\model\AccessToken();
        @$token_model->saveAccessTokenData($provider, $result['app_account'], $token_info);

        // 获取第三方平台用户的openID
        $openid = $this->_getProviderOpenId($provider, $token_info);

        $user_model = new \app\common\model\User();
        $where      = ['provider'=>$provider, 'openid'=>$openid];
        $user_info  = $user_model->where($where)->find();
        $out_time   = date('Y-m-d H:i:s', strtotime('-7 day'));
        if (!empty($user_info) && $user_info['sync_time'] > $out_time) {
            set_login_cookie($user_info);
            header('location: ' . $back_url);
            die;
        }

        // 获取第三方用户信息，同步到本地
        $user_res = $oauthProvider->getUserInfo($token_info['access_token'], $openid);
        if (empty($user_res)) {
            $this->error('未获取到用户信息，请重新授权登录');
        }
        $user_res = json_decode($user_res, true);
        if (!empty($user_res['error_code'])) {
            $this->error('授权登录错误，错误码：' . $user_res['error_code'] . '；Error：' . $user_res['error']);
        }
        // 判断是更新还是添加新用户
        if (!empty($user_info)) {
            $res = $user_model->updateOauthUser($provider, $user_info['id'], $user_res);
        } else {
            $res = $user_model->saveOauthUser($provider, $openid, $user_res);
        }        
        if ($res['code'] == 1) {
            $this->error($res['msg']);
        }
        set_login_cookie($res['data']);
        header('location: ' . $back_url);
    }

    /**
     * 获取平台第三方openID值
     * @param  string $provider   平台参数
     * @param  array  $token_info 平台返回token信息
     * @return string|void
     */
    private function _getProviderOpenId($provider = '', $token_info = [])
    {
        switch ($provider) {
            case 'weibo':
                $openid = $token_info['uid'];
                break;
            case 'qq':
                $openid = $token_info['openid'];
                break;
        }

        return $openid;
    }

}
